package com.mkx.performance;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 性能测试基类，提供通用的性能测试功能
 */
public abstract class PerformanceTestBase {
    // 测试数据规模
    protected static final int SMALL_SIZE = 10_000;
    protected static final int MEDIUM_SIZE = 100_000;
    protected static final int LARGE_SIZE = 1_000_000;
    
    // 重复测试次数以获得平均值
    protected static final int WARMUP_ITERATIONS = 3;
    protected static final int TEST_ITERATIONS = 5;
    
    // 统计指标
    protected AtomicLong totalTime = new AtomicLong(0);
    protected AtomicLong minTime = new AtomicLong(Long.MAX_VALUE);
    protected AtomicLong maxTime = new AtomicLong(0);
    protected AtomicInteger operationCount = new AtomicInteger(0);
    
    /**
     * 重置统计数据
     */
    protected void resetStatistics() {
        totalTime.set(0);
        minTime.set(Long.MAX_VALUE);
        maxTime.set(0);
        operationCount.set(0);
    }
    
    /**
     * 更新时间统计
     */
    protected void updateTimeStatistics(long time) {
        totalTime.addAndGet(time);
        minTime.updateAndGet(current -> Math.min(current, time));
        maxTime.updateAndGet(current -> Math.max(current, time));
        operationCount.incrementAndGet();
    }
    
    /**
     * 执行预热运行
     */
    protected void warmup(Runnable testRunnable) {
        System.out.println("=== 预热阶段 ===");
        for (int i = 0; i < WARMUP_ITERATIONS; i++) {
            System.out.println("预热迭代 " + (i + 1) + "/" + WARMUP_ITERATIONS);
            testRunnable.run();
        }
        System.out.println("=== 预热完成 ===");
    }
    
    /**
     * 执行实际测试并收集统计信息
     */
    protected void runTest(Runnable testRunnable) {
        resetStatistics();
        System.out.println("=== 测试执行阶段 ===");
        
        for (int i = 0; i < TEST_ITERATIONS; i++) {
            System.out.println("测试迭代 " + (i + 1) + "/" + TEST_ITERATIONS);
            long startTime = System.nanoTime();
            testRunnable.run();
            long endTime = System.nanoTime();
            long durationNanos = endTime - startTime;
            updateTimeStatistics(durationNanos);
        }
        
        System.out.println("=== 测试完成 ===");
    }
    
    /**
     * 打印性能统计信息
     */
    protected void printPerformanceStatistics(String operationName) {
        double avgTimeNanos = totalTime.get() / (double) operationCount.get();
        double avgTimeMicros = avgTimeNanos / 1000;
        double avgTimeMillis = avgTimeMicros / 1000;
        
        System.out.println("\n=== " + operationName + " 性能统计 ===");
        System.out.println("总操作次数: " + operationCount.get());
        System.out.println("总执行时间: " + (totalTime.get() / 1_000_000) + " ms");
        System.out.println("平均执行时间: " + String.format("%.2f", avgTimeNanos) + " ns");
        System.out.println("平均执行时间: " + String.format("%.2f", avgTimeMicros) + " μs");
        System.out.println("平均执行时间: " + String.format("%.2f", avgTimeMillis) + " ms");
        System.out.println("最小执行时间: " + (minTime.get() / 1_000_000) + " ms");
        System.out.println("最大执行时间: " + (maxTime.get() / 1_000_000) + " ms");
        System.out.println("每秒操作数 (TPS): " + String.format("%.2f", 1_000_000_000.0 / avgTimeNanos));
    }
}